package com.productAndConsume;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

// 生产者-> 缓冲区 <-消费者
public class TestLockPC3 {
    public static void main(String[] args) {
        SyncStack ss = new SyncStack();
        Produce pd = new Produce(ss);
        Consume cs = new Consume(ss);
        Thread t1 = new Thread(pd,"A");
        Thread t2 = new Thread(cs,"B");
        t2.start();
        t1.start();

//        Thread.State state1 = t1.getState();
//        Thread.State state2 = t2.getState();
//        while (state1!=Thread.State.TERMINATED || state2!=Thread.State.TERMINATED){
//            state1 = t1.getState();
//            state2 = t2.getState();
//            System.out.println("A状态："+state1+",B状态："+state2);
//            try {
//                Thread.sleep(500);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }
    }
}

/*
 * 馒头实体类
 */
class ManTou {
    private int id;

    public ManTou(int id) {
        this.id = id;
    }

    public int getId() {
        return this.id;
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "ManTou " + getId();
    }
}

/*
 * 馒头框类
 */
class SyncStack {
    Lock lock = new ReentrantLock();
    Condition pro = lock.newCondition();
    Condition consume = lock.newCondition();
    int index = 0;
    ManTou[] mtArray = new ManTou[6];//实体数组 一次6个

    public void push(ManTou mt) {
        lock.lock();
        try {
            while (index == mtArray.length) {//长度6
                try {
                    pro.await();  // full 指当前线程
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            consume.signal();//通知其他线程 唤醒之前将当前线程移动到同步队列
            mtArray[index] = mt;//对象 mt==index
            index++;
            System.out.println("index---->"+index);

            System.out.println(Thread.currentThread().getName()+"生产了" + mt);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void pop() {
        lock.lock();
        try {
            while (index == 0) {
                try {
                    consume.await();// 空 当前线程进入等待
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            pro.signal();
            index--;
            System.out.println("index pop--"+index);
            System.out.println("消费了" + mtArray[index]);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

/*
 * 生产者
 */
class Produce implements Runnable {
    SyncStack ss = null;

    public Produce(SyncStack ss) {
        this.ss = ss;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 20; i++) {//19次
            ManTou mt = new ManTou(i);
            if (ss != null) {
                ss.push(mt);
            }
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}

/*
 * 消费者
 */
class Consume implements Runnable {
    SyncStack ss = null;

    public Consume(SyncStack ss) {
        this.ss = ss;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        for (int i = 0; i < 20; i++) {
            if (ss != null) {
                ss.pop();
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}
